#include <functional>
#include <iostream>
#include <thread>
#include <list>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h> 
#include <arpa/inet.h>

#include "network.h"
#include "xap.h"

/**
  ******************************************************************************
  * @file           : network.cpp
  * @brief          : implement for network.cpp file.
  *                   This file contains the common implement of the application.
  * @author			: ac
  * @attention
  *
  *		Copyright (c) 2023 Technology Co., Ltd.
  *
  *******************************************************************************
  */


/*
 * globla variable
 */


int client_fd = -1;
struct sockaddr_in ser_addr;
struct timeval ta;


/**
 * udp_init - udp init function.
 * @none
 */
int udp_init(void)
{
	pthread_attr_t attr;
	pthread_t rid; 

    client_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(client_fd < 0)
    {
        printf("create socket fail!\n");
        return -1;
    }
	printf("udp client fd:%d\n", client_fd);

    memset(&ser_addr, 0, sizeof(ser_addr));
    ser_addr.sin_family = AF_INET;
    ser_addr.sin_addr.s_addr = inet_addr(RTK_UDP_SERVER_IP);
    ser_addr.sin_port = htons(RTK_UDP_SERVER_PORT); 

	pthread_attr_init(&attr);
	pthread_create(&rid, &attr, (void * (*)(void *))udp_recv, NULL);

    //close(client_fd);

    return 0;
}

bool udp_send_data(SOCKET SocketFd,const char *pSerIP,unsigned short Port,void *pBuff, int len)
{
	struct sockaddr_in	server;
	int i = 0;

	if(SocketFd < 0) 
		return -1;

	//memset(&server,0,sizeof(server));
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = inet_addr(pSerIP);
	server.sin_port = htons((unsigned short)Port);

	return (sendto(SocketFd,(const char *)pBuff, len, 0, (struct sockaddr*)&server, sizeof(server)) != -1) ? true : false;
}

void udp_send_msg(int fd, struct sockaddr* dst, unsigned char * buf, int b_len)
{
    socklen_t len;
	int i = 0;

	len = sizeof(*dst);	
	sendto(fd, buf, b_len, 0, dst, len);
	
	#if 0
	printf("send:\n");
	for (i = 0; i < b_len; i++) {
		printf("%.2x ", buf[i]);
	}
	printf("\nend:\n");	// 去掉会延时输出，需找找原因
	#endif
}

void handle_udp_msg(int fd)
{
    unsigned char buf[BUFF_LEN];  //接收缓冲区，1024字节
    socklen_t len;
    int count = 0, i = 0;
    struct sockaddr_in clent_addr;  //clent_addr 用于记录发送方的地址信息
	struct timeval start, end;
	float  timeuse;

    while(1)
    {
        memset(buf, 0, BUFF_LEN);
        len = sizeof(clent_addr);

		// 拍照
		//system("camera_if_direct 0x0 0xb 0x3");

		gettimeofday( &start, NULL );
        count = recvfrom(fd, buf, BUFF_LEN, 0, (struct sockaddr*)&clent_addr, &len);  //recvfrom是拥塞函数，没有数据就一直拥塞
        if(count == -1) 
        {
            printf("recieve data fail!\n");
            return;
        }
		gettimeofday( &end, NULL );

		timeuse = 1000000 * ( end.tv_sec - start.tv_sec ) + (end.tv_usec - start.tv_usec); 
		timeuse /= 1000;
		printf("--- recvfrom timeuse = %f\n", timeuse);
		
		timeuse = 0.0;
		timeuse = 1000000 * ( end.tv_sec - ta.tv_sec ) + (end.tv_usec - ta.tv_usec); 
		timeuse /= 1000;
		printf("--- send->recv timeuse = %f\n", timeuse);

		#if 0
        printf("------------- %s -----------\n", "begin");
        for (i = 0; i < count; i++) {
            printf("%.2x ",buf[i]);
        }
        printf("\n------------- %s -----------\n", "end");
		#endif

		analysis(buf, count);
		
		usleep(50000);
    }
}

void * udp_recv(void *arg)
{
	handle_udp_msg(client_fd);   

	return 0;
}

void udp_uninit()
{
	close(client_fd);
}

void * tcp_recv(void *arg)
{
	char recv_buff[BUFF_LEN] = {0};
	int count = 0, i = 0;
    
    while(1) {
		recv(client_fd, recv_buff, sizeof(recv_buff)-1, 0);

		printf("------------- %s -----------\n", "begin");
        for (i = 0; i < count; i++) {
            printf("%.2x ",recv_buff[i]);
        }
        printf("------------- %s -----------\n", "end");

		usleep(50000);
    }    
}

int tcp_send(char *psend, int len)
{
	int count = 0;

	count = send(client_fd, psend, len + 1, 0);

	return count;
}

int tcp_init()
{
	pthread_attr_t attr;
	pthread_t rid;   

    client_fd = socket(AF_INET, SOCK_STREAM, 0);
	printf("tcp client fd:%d\n", client_fd);

    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  
    serv_addr.sin_family = AF_INET;  
    serv_addr.sin_addr.s_addr = inet_addr("172.31.0.1");  
    serv_addr.sin_port = htons(10087);  

	pthread_attr_init(&attr);
    
    while (connect(client_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))) {
        sleep(1);
        printf("wait serve connect\r\n");
    }    
         
    pthread_create(&rid, &attr, (void * (*)(void *))tcp_recv, NULL);
    
    return 0;
}

void tcp_uninit()
{
	close(client_fd);
}






